package com.wiegand.facebook {
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.external.ExternalInterface;
	import flash.utils.Timer;

	/**
	 * @author gandy
	 */
	public class Facebook extends EventDispatcher{

		private var _readyTimer : Timer;
		private var _jsReady : Boolean = false;
		
		private static var _instance : Facebook;
		
		public static function getInstance() : Facebook{
			if( _instance == null ) _instance = new Facebook( new SingletonEnforecer() );
			return _instance;
		}
		
		public function Facebook( blocker:SingletonEnforecer ):void{
			if ( blocker == null ) {
            	throw new Error("Error: Instantiation failed: Use Facebook.getInstance() instead of new.");
          	}
          	else init();	
		}
		
		private function init() : void{
	
		}
		
		public function checkJS():void{
			try{
	          if (ExternalInterface.available) { 
	                try{ 
	                    if (checkJavaScriptReady()) { 
	                        addJsCallBacks();
	                    } else { 
	                        trace("js is not ready..."); 
	                        _readyTimer = new Timer(100, 100); 
	                        _readyTimer.addEventListener(TimerEvent.TIMER, timerHandler); 
	                        _readyTimer.start(); 
	                    } 
	                } catch (error:SecurityError) { 
	                    trace("A SecurityError occurred: " + error.message + "\n"); 
	                } catch (error:Error) { 
	                    trace("An Error occurred: " + error.message + "\n"); 
	                } 
	            } 
            }catch(e:Error){
            	  trace("External interface is not available..."); 
            } 
		}		
		
		private function timerHandler(event:TimerEvent):void { 
            if( _readyTimer.repeatCount == _readyTimer.currentCount ){
            	cleanTimer();
			}
			if( checkJavaScriptReady() ){
				addJsCallBacks();
			}
		}
		
		private function checkJavaScriptReady():Boolean { 
		    var isReady:Boolean = ExternalInterface.call("isReady"); 
		    return isReady; 
		} 
		
		private function cleanTimer() : void {
		    _readyTimer.removeEventListener(TimerEvent.TIMER, timerHandler); 
        	_readyTimer.stop();
			_readyTimer.reset();
		}

		private function addJsCallBacks():void{
 			trace("js is ready.."); 
		  	trace("adding callback...\n"); 
		  	cleanTimer();
			_jsReady = true;
           	ExternalInterface.addCallback("sendToActionScript",receivedFromJavaScript);			        
		}

		private function receivedFromJavaScript(value:String):void { 
		    trace("Flash... JavaScript says: " + value + "\n"); 
		} 
		
		public function doCallToJS(value:String):void{
			trace("try to call js");
			if( ExternalInterface.available && _jsReady ) ExternalInterface.call("sendToJavaScript", value);
		}
		
		public function login():void{
			if( ExternalInterface.available && _jsReady ){ 
				ExternalInterface.addCallback("onLogin", onLogin);
				ExternalInterface.call("login");
			}
		}
		
		private function onLogin() : void {
			trace("onLogin");
			dispatchEvent( new FacebookEvent(FacebookEvent.EVENT_FB_ONLOGIN) );
		}
		
		public function streamPublish(user_message:String, attachment:Object, action_links:Object):void{
			if( ExternalInterface.available && _jsReady ){ 
				ExternalInterface.call("streamPublish", user_message, attachment, action_links);
			}		
		}
		
	}
}

internal class SingletonEnforecer {}
